using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using viBook.Helpers;
using viBook.ModelBinders;
using viBook.Models;

namespace viBook.Controllers
{
    public class BooksController : BaseController
    {
        #region Constructors and Repository vars

        private readonly IAuthorRepository _authorRepository;
        private readonly IBookRepository _bookRepository;
        private readonly ICategoryRepository _categoryRepository;
        private readonly IChapterRepository _chapterRepository;

        public BooksController()
            : this(new BookRepository(), new CategoryRepository(), new AuthorRepository(), new ChapterRepository())
        {
        }

        public BooksController(IBookRepository bookRepository, ICategoryRepository categoryRepository,
                               IAuthorRepository authorRepository, IChapterRepository chapterRepository)
        {
            _categoryRepository = categoryRepository;
            _bookRepository = bookRepository;
            _authorRepository = authorRepository;
            _chapterRepository = chapterRepository;
        }

        #endregion

        public ViewResult Index()
        {
            return View(_bookRepository.FindAllBookByUserId(ExtendedIdentity.Id));
        }

        //
        // GET: /Books/Details/5

        public ViewResult Details(int id)
        {
            Book book = _bookRepository.Find(id);
            //apply for book have chapter
            if (book.HasChapters)
            {
                //load category
                var categoryCollection = new List<SelectListItem>();
                foreach (Category category in _categoryRepository.All)
                {
                    categoryCollection.Add(new SelectListItem
                                               {
                                                   Selected = false,
                                                   Value = category.Id.ToString(),
                                                   Text = category.CategoryName
                                               });
                }
                ViewBag.CategoryCollection = categoryCollection;
                //load chapter detail of book
                book.Chapters = _chapterRepository.GetAllChaptersByBookId(id);
                return View(book);
            }
            else
                return null;
        }

        [Authorize]
        public ActionResult Create()
        {
            var categoryCollection = new List<SelectListItem>();
            foreach (Category category in _categoryRepository.All)
            {
                categoryCollection.Add(new SelectListItem
                                           {
                                               Selected = false,
                                               Value = category.Id.ToString(),
                                               Text = category.CategoryName
                                           });
            }
            ViewBag.CategoryCollection = categoryCollection;
            return View(new Book());
        }

        [HttpPost, Authorize]
        public ActionResult Create([ModelBinder(typeof(BookBinders))] Book book)
        {
            if (ModelState.IsValid)
            {
                book.CoverUrl = Request["filesUploaded"];
                book.AuthorId = _authorRepository.FindAuthorsiId(book.AuthorName);
                _bookRepository.InsertOrUpdate(book);
                _bookRepository.Save();
                return RedirectToAction("Index");
            }
            else
            {
                var categoryCollection = new List<SelectListItem>();
                foreach (Category category in _categoryRepository.All)
                {
                    categoryCollection.Add(new SelectListItem
                                               {
                                                   Selected = false,
                                                   Value = category.Id.ToString(),
                                                   Text = category.CategoryName
                                               });
                }
                ViewBag.CategoryCollection = categoryCollection;
                return View(new Book());
            }
        }

        [Authorize]
        public ActionResult Edit(int id)
        {
            PopuplateCategories();
            return View(_bookRepository.Find(id));
        }

        [HttpPost]
        public ActionResult Edit(Book book)
        {
            if (ModelState.IsValid)
            {
                book.AuthorId = _authorRepository.FindAuthorsiId(book.AuthorName);
                if (!string.IsNullOrEmpty(Request["filesUploaded"]))
                    book.CoverUrl = Request["filesUploaded"];
                _bookRepository.InsertOrUpdate(book);
                _bookRepository.Save();
                return RedirectToAction("Index");
            }
            else
            {
                return RedirectToAction("Details", "Books", new { id = book.Id });
            }
        }

        //
        // POST: /Books/Delete/5

        [HttpPost]
        public JsonResult DeleteConfirmed(int id)
        {
            _bookRepository.Delete(id);
            _bookRepository.Save();
            return Json(new { success = true });
        }

        public Image Resize(Image img, int percentage)
        {
            //get the height and width of the image
            int originalW = img.Width;
            int originalH = img.Height;

            //get the new size based on the percentage change
            int resizedW = (originalW / percentage);
            int resizedH = (originalH / percentage);

            //create a new Bitmap the size of the new image
            var bmp = new Bitmap(resizedW, resizedH);
            //create a new graphic from the Bitmap
            Graphics graphic = Graphics.FromImage(bmp);
            graphic.InterpolationMode = InterpolationMode.HighQualityBicubic;
            //draw the newly resized image
            graphic.DrawImage(img, 0, 0, resizedW, resizedH);
            //dispose and free up the resources
            graphic.Dispose();
            //return the image
            return bmp;
        }

        //todo: Why return string here?
        public string UploadImage([ModelBinder(typeof(ImageUploadModelBinder))] dynamic fileInfo)
        {
            string fileName = fileInfo.FileName;
            HttpPostedFileBase fileData = fileInfo.FileData;
            if (string.IsNullOrEmpty(fileName) || fileData == null)
            {
                return "Upload Failed!";
            }
            string imagePath = this.FileNameFormatter(fileName);
            string thumbnailPath = this.FileNameFormatter(fileName, "thumb_");
            this.SaveFile(fileData, imagePath, thumbnailPath);
            return "Upload OK! " + imagePath;
        }

        private void PopuplateCategories()
        {
            ViewBag.CategoryCollection = _categoryRepository.All.ToList().Select(category => new SelectListItem
                                                                                                 {
                                                                                                     Selected = false,
                                                                                                     Value =
                                                                                                         category.Id.
                                                                                                         ToString(),
                                                                                                     Text =
                                                                                                         category.
                                                                                                         CategoryName
                                                                                                 });
        }
    }
}